<?php

namespace common\models\user;

use Yii;
use common\models\shop\ShopCouponScope;
use common\logics\shop\CouponTypeLogic;

/**
 * This is the model class for table "{{%user_coupon}}".
 *
 * @property int $id
 * @property int $user_id 用户ID
 * @property int $coupon_id 卡券ID
 * @property int $store_id 卡券适用店铺ID
 * @property string|null $model 使用模型
 * @property int $model_id 使用模型ID
 * @property int $start_at 可用开始时间
 * @property int $expired_at 过期时间
 * @property int $usage_time 使用时间
 * @property int $status 状态
 * @property int $created_at 创建时间
 * @property int $updated_at 更新时间
 * @property int $deleted_at 删除时间
 */
class UserCoupon extends \common\db\ActiveRecord {

    /**
     * @var const 用户优惠券状态
     * ```
     * 未使用：0
     * 使用中：10
     * 已使用：20
     * ```
     */
    const STATUS_DEFAULT = 0;
    const STATUS_ACTIVE = 10;
    const STATUS_USED = 20;

    /**
     * {@inheritdoc}
     */
    public static function tableName() {
        return '{{%user_coupon}}';
    }

    /**
     * {@inheritdoc}
     */
    public function rules() {
        return [
            [['user_id', 'coupon_id', 'store_id', 'model_id', 'start_at', 'expired_at', 'usage_time', 'status', 'created_at', 'updated_at', 'deleted_at'], 'integer'],
            [['model'], 'string', 'max' => 100],
        ];
    }

    /**
     * {@inheritdoc}
     */
    public function attributeLabels() {
        return [
            'id' => 'ID',
            'user_id' => '用户ID',
            'coupon_id' => '卡券ID',
            'store_id' => '卡券适用店铺ID',
            'model' => '使用模型',
            'model_id' => '使用模型ID',
            'start_at' => '可用开始时间',
            'expired_at' => '过期时间',
            'usage_time' => '使用时间',
            'status' => '状态',
            'created_at' => '创建时间',
            'updated_at' => '更新时间',
            'deleted_at' => '删除时间',
        ];
    }

    /**
     * 关联优惠券基础信息
     * @return \common\db\ActiveQuery
     */
    public function getCoupon() {
        return $this->hasOne(\common\models\shop\ShopCoupon::class, ['id' => 'coupon_id']);
    }

    /**
     * 关联优惠券适用店铺信息
     * @return \common\db\ActiveQuery
     */
    public function getStore() {
        return $this->hasOne(\common\logics\shop\ShopStoreCell::class, ['id' => 'store_id']);
    }

    /**
     * 优惠券类型
     * @return CouponTypeLogic|null
     */
    public function getCouponType() {
        if ($this->coupon) {
            $type = new CouponTypeLogic();
            $type->setAttributes([
                'store_id' => $this->coupon->store_id,
                'scope' => $this->coupon->scope,
                'limit' => $this->coupon->limit,
                'discount' => $this->coupon->discount,
                'layout' => 'right',
            ]);
            return $type;
        }
        return null;
    }

    /**
     * 是否新到
     * @return bool
     */
    public function getNewest() {
        return (time() - $this->created_at) < 86400;
    }

    /**
     * 当前优惠券是否有效
     * @return bool
     */
    public function getAvilabled() {
        if ($this->status !== static::STATUS_DEFAULT || $this->usage_time) {
            return false;
        }
        if ($this->expired_at && $this->expired_at < time()) {
            return false;
        }
        return true;
    }

    /**
     * 当前优惠券当前是否可用
     * @return bool
     */
    public function getEnabled() {
        if (!$this->getAvilabled()) {
            return false;
        }
        if ($this->start_at && $this->start_at > time()) {
            return false;
        }
        return true;
    }

    /**
     * 
     * @param type $uid
     * @return \common\db\ActiveQuery
     */
    public static function findAvailable($uid) {
        $query = static::find()->alias('t')->active()->andWhere([
            'and',
            ['t.user_id' => $uid],
            ['t.status' => static::STATUS_DEFAULT],
            ['>=', 't.expired_at', time()]
        ]);
        return $query;
    }

    /**
     * 根据用户ID获取用户可用的优惠券
     * 
     * @param integer $uid
     * @return \common\db\ActiveQuery
     */
    public static function findAvilable($uid = null, $alias = 't') {
        if (!$uid && !Yii::$app->user->isGuest) {
            $uid = Yii::$app->user->id;
        }
        $query = static::findActive($alias, static::STATUS_DEFAULT);
        if ($alias) {
            $alias .= '.';
        }
        $query->andWhere([
            'and',
            [$alias . 'user_id' => $uid],
            [$alias . 'usage_time' => 0],
            [
                'or',
                [$alias . 'start_at' => 0],
                ['<=', $alias . 'start_at', time()],
            ],
            [
                'or',
                [$alias . 'expired_at' => 0],
                ['>', $alias . 'expired_at', time()],
            ]
        ]);
        $query->innerJoinWith('coupon coupon');
        $query->debug();
        return $query;
    }

    public function getCouponNo() {
        return implode([
            date('y', $this->created_at),
            str_pad(date('z', $this->created_at), 3, "0"),
            str_pad($this->id, 7, "0", STR_PAD_LEFT),
        ]);
    }

    /**
     * 卡券有效期
     * @return string
     */
    public function getEffectiveTime() {
        $starttime = $this->start_at ?: time();
        $split = '-';
        $endtime = '';
        if ($this->expired_at) {
            $endtime = date('Y.m.d', $this->expired_at);
        } else {
            $split = '起可用';
        }
        return Yii::t('message', '{begin}{split}{end}', [
            'begin' => date('Y.m.d', $starttime),
            'split' => $split,
            'end' => $endtime,
        ]);
    }

    /**
     * 卡券限制范围
     * @return integer
     */
    public function getScopeId() {
        return $this->coupon->scope_id;
    }

    /**
     * 卡券限制范围内容
     * @return \common\db\ActiveQuery
     */
    public function getScopeItems() {
        return $this->hasMany(\common\models\shop\ShopCouponItem::class, ['coupon_id' => 'coupon_id']);
    }

    /**
     * 卡券是否包含邮费
     * @return integer
     */
    public function getIncludeFreight() {
        return $this->coupon->include_freight;
    }

    /**
     * 卡券描述
     * @return string
     */
    public function getDescription() {
        return $this->coupon->description;
    }

    /**
     * 卡券名称
     * @return string
     */
    public function getName() {
        return $this->coupon->name;
    }

    /**
     * 卡券标题
     * @return string
     */
    public function getTitle() {
        return $this->coupon->title;
    }

    /**
     * 卡券条件规则
     * @return string
     */
    public function getCondition() {
        return $this->coupon->condition;
    }

    /**
     * 卡券是否可叠加使用
     * @return bool
     */
    public function getMutex() {
        return boolval($this->coupon->mutex);
    }

    /**
     * 卡券优惠数值
     * @return float|integer
     */
    public function getValue() {
        return $this->coupon->value;
    }

    /**
     * 卡券优惠数值单位
     * @return bool
     */
    public function getValueUnit() {
        return $this->coupon->valueUnit;
    }

    public static function computeOwnCoupons($uid, &$amount = 0) {
        $query = static::findAvilable($uid, 't');
        $query->select([
            't.coupon_id',
            'coupon.store_id',
            'coupon.scope_id',
            'count' => 'count(*)',
        ]);
        $query->groupBy([
            'coupon.store_id',
            'coupon.scope_id',
        ]);
        $userCoupons = $query->asArray()->all();
        $stats = [];
        foreach ($userCoupons as $item) {
            $nums = (int) $item['count'];
            $amount += $nums;
            if ($item['store_id']) {
                $key = ShopCouponScope::SCOPE_NAME_STORE;
            } else {
                if (!$item['scope_id']) {
                    $key = ShopCouponScope::SCOPE_NAME_PLATFORM;
                } else {
                    $key = $item['scope_id'];
                }
            }
            if (!isset($stats[$key])) {
                $stats[$key] = $nums;
            } else {
                $stats[$key] += $nums;
            }
        }
        return $stats;
    }

    public static function findDrawOrUsed($uid) {
        $query = static::find()->alias('t')->active()->andWhere([
            'and',
            ['t.user_id' => $uid],
            [
                'or',
                [
                    //已领取未使用未过期
                    'and',
                    ['t.status' => static::STATUS_DEFAULT],
                    ['>=', 't.expired_at', time()],
                    ['t.usage_time' => 0]
                ],
                [
                    //已使用或者正在使用
                    'and',
                    ['>=', 't.status', static::STATUS_USED],
                    ['t.usage_time' => 0]
                ]
            ]
        ]);
        return $query;
    }

    /**
     * {@inheritdoc}
     */
    public function fields() {
        return [
            'id',
            'title',
            'name',
            'description',
            'scope_id' => 'scopeId',
            'include_freight' => 'includeFreight',
            'condition',
            'mutex',
            'value',
            'valueUnit',
            'effectiveTime',
        ];
    }

}
